import datetime
import random
import time

import requests,json
from db import db
from utils.myredis import r
from views.base import BaseHandler
from utils.comm import gettoken, get_ali_object

# 启动雪花算法
# snowflake_start_server --worker=1
import snowflake.client
def create_ordercode(tablename,count):
    # 雪花算法生成唯一id
    code = snowflake.client.get_guid()
    # 用redis解决始终回拨，根据key查询上一次存入的结果，
    # 和当前生成的对比，如果当前小于redis中存储的，说明发生时钟回拨
    # 先取
    value = r.str_get(tablename)
    # 判断是否存在
    if value:
        # 当前时间 小于 redis中存储的时间
        if int(code) < int(value):
            # 重新调用  雪花算法生成唯一id
            create_ordercode(tablename,count)
    # 把最后一次生成的存入redis
    r.set_str(tablename,code)
    # 取模获取列表
    number = hash(code)%int(count)
    print("number",number)
    if number == 0:
        return tablename,code
    else:
        return tablename + str(number),code

class LandmarkHanddler(BaseHandler):
    def post(self):
        # 获取页面参数
        data = json.loads(self.request.body)
        tmoney = int(data["tmoney"])
        purpose = data["purpose"]
        descrip = data["descrip"]
        term = int(data["term"])
        pay_type = int(data["pay_type"])
        interest_rate = data["interest_rate"]
        userid = int(data["userid"])
        tablename,code = create_ordercode('landmarks',3)
        print(tablename,code)
        if not all([tmoney,purpose,descrip,term,pay_type,interest_rate,userid]):
            return self.finish({"code": 400, "msg":"字段不能为空"})
        sql = """insert into %s(money,code,tmoney,purpose,descrip,term,pay_type,interest_rate,userid) values (%d,%d,%d,'%s','%s',%d,%d,'%s',%d)"""%(tablename,tmoney,int(code),tmoney,purpose,descrip,term,pay_type,interest_rate,userid)
        db.add(sql)
        db.commit()
        r.list_push("landmarkss",code)
        return self.finish({"code": 200, "msg": "资料审核中"})


def set_audit():
    # 查询所有审核员角色表中添加一个角色审核员 添加两个用户分配角色
    sql = "select id from admin_user where roleid=25"
    res = db.findAll(sql)
    for i in res:
        # 获取队列的数据
        code = r.list_pop("landmarkss")
        # 不为空
        if code != None:
            # 哈希取模
            number = hash(int(code.decode())) % 3
            print("number", number)
            if number == 0:
                sqls = "update landmarks set audit_userid=%d where code=%d" % (int(i["id"]), int(code))
                db.add(sqls)
                db.commit()
                print("if标的分配成功")
            else:
                landmarks = "landmarks" + str(number)
                sql1 = "update %s set audit_userid=%d where code=%d" % (landmarks,int(i["id"]),int(code))
                db.add(sql1)
                db.commit()
                print("标的分配成功")
        else:
            print("队列没有数据")

class getlandmarks(BaseHandler):
    def get(self):
        page = self.get_query_argument("page")
        page_size = self.get_query_argument("page_size")
        key = "landmarks" + str(page)
        # r.del_key(key + "setnx")
        lst = r.str_get(key)
        if lst:
            lst = json.loads(lst)
        else:
            # print("else")
            start = (int(page) - 1) * int(page_size)
            # 并发访问同时操作数据库，解决方案分布式锁
            flag = r.str_setnx(key+"setnx",1)
            # print("fal",flag)
            if flag == True:
                # print(">>>")
                sqls = "select *  from (select * from landmarks where status=1 union all select * from landmarks1 where status=1 union all select * from landmarks2 where status=1) as t limit %d,%d"%(int(start),int(page_size))
                # print(sqls)
                list = db.findAll(sqls)
                # print("lst",list)
                lst = []
                for i in list:
                    i["code"] = str(i["code"])
                    i["interest_rate"] = float(i["interest_rate"])
                    i['audit_time'] = datetime.datetime.strftime(i['audit_time'], "%Y-%m-%d %H:%M:%S")
                    lst.append(i)
                r.str_add(key,json.dumps(list))
                r.del_key(key+"setnx")
        sql1 = "select count(code) as a  from (select * from landmarks where status=1 union all select * from landmarks1 where status=1 union all select * from landmarks2 where status=1) as t"
        res = db.findone(sql1)
        total = res["a"]
        self.finish({"code": 200,"total":total,"data":lst})





class Setorder(BaseHandler):
    def post(self):
        data = json.loads(self.request.body)
        userid = data["userid"]
        money = data["money"]
        # 生成订单时间
        create_time = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S")
        # 订单号
        number = str(int(time.time()))+str(userid) + str(random.randint(10000, 99999))
        sql = "insert into orders(userid, serial_number, money, create_time) values (%d,'%s','%s','%s')"%(int(userid),number,money,create_time)
        db.add(sql)
        db.commit()
        # 对生成半小时没支付的订单处理解决
        # 记录过期时间
        times= int(time.time()) + 1800
        # 加入队列
        r.sortedset_add("cancelOredrs",number,times)
        alipay = get_ali_object()
        query_params = alipay.direct_pay(
            subject=str(userid) + ",订单",  # 商品简单描述
            # 用户购买的商品订单号（每次不一样） 20180301073422891
            out_trade_no=str(number),
            total_amount=money,  # 交易金额(单位: 元 保留俩位小数)
        )
        # 支付宝网关地址（沙箱应用）
        pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(
            query_params)
        self.write({"code":200,"url":pay_url})

class Callback(BaseHandler):
    def get(self):
        # 获取支付返回的参数
        data = self.request.arguments
        # 对参数进行处理
        datas = {k:v[0].decode() for k,v in data.items()}
        # print(datas)
        # 从字典中将sign删除
        sign = datas.pop("sign")
        # 获取支付宝对象
        alipay = get_ali_object()
        # 调用验签
        flag = alipay.verify(datas,sign)
        # print(flag)
        number = datas.pop("out_trade_no")
        if flag == True:
            r.sortedset_delete("cancelOredrs",number)
            try:
                sql2 = "select * from orders where serial_number='%s'"%(number)
                res = db.findone(sql2)
                # 跟新充值订单状态
                sql = "update orders set status=1 where serial_number='%s'"%(number)
                db.add(sql)
                # 更新用户账号金额
                sql1 = "update user set money='%s' where id=%d"%(res["money"],int(res["userid"]))
                db.add(sql1)
                # 写入金额记录表
                sql4 = "insert into money_orders(userid, serial_number, money) values (%d,'%s','%s')"%(int(res["userid"]),number,res["money"])
                db.add(sql4)
                db.commit()
                self.redirect("http://localhost:8080/")
            except Exception as a:
                print(a)
                return self.finish({"code": 400, "msg":"错误"})

# 删除队列中半个小时已过期的数据
def Paymentfailure():
    res = r.sortedset_getall("cancelOredrs")
    if res:
        times = int(time.time()) + 1800
        # 获取这个区间的数据
        timess = r.sortedset_getbyscore("cancelOredrs", 0, times)
        pay = get_ali_object()
        for i in timess:
            # 通过订单号向支付宝发起请求获取结果
            query_params = pay.query_pay(
                # 用户购买的商品订单号（每次不一样） 20180301073422891
                out_trade_no=i.decode(),
            )
            # 支付宝网关地址（沙箱应用）
            pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(
                query_params)
            res = requests.get(pay_url)
            res=json.loads(res.text)
            # 根据结果判断，如果成功更新订单，如果失败清除订单，清除队列中的信息
            if res["alipay_trade_query_response"]["code"] == 10000:
                try:
                    sql2 = "select * from orders where serial_number='%s'" % (i.decode())
                    res = db.findone(sql2)
                    # 跟新充值订单状态
                    sql = "update orders set status=1 where serial_number='%s'" % (i.decode())
                    db.add(sql)
                    # 更新用户账号金额
                    sql1 = "update user set money='%s' where id=%d" % (res["money"], int(res["userid"]))
                    db.add(sql1)
                    # 写入金额记录表
                    sql4 = "insert into money_orders(userid, serial_number, money) values (%d,'%s','%s')" % (
                    int(res["userid"]), i.decode(), res["money"])
                    db.add(sql4)
                    db.commit()
                except Exception as a:
                    print(a)
                    print("******更新订单*******")

            else:
                # 如果失败清除订单，清除队列中的信息
                r.sortedset_delete("cancelOredrs", i)
                sql = "delete from orders where serial_number='%s'"%(i.decode())
                db.add(sql)
                db.commit()
                print("******清除队列*******")
    else:
        return "没有数据"




# 二分法
# list = [1,9,4,5,6,7]
# 排序
# list1 = sorted(list)
# def search(list1,number):
#     lens = len(list1)
#     start = 0
#     end = lens - 1
#     while start <= end:
#         mid = (start+end)//2
#         if list1[mid] == number:
#             return mid
#         elif number < list1[mid]:
#             end = mid -1
#         else:
#             start = mid +1
# print(search(list1,1))
# print(search(list1,9))
# print(search(list1,8))
